package com.zyd.service.enclosure.impl;

import com.zyd.constants.ErrorDef;
import com.zyd.context.HeaderContext;
import com.zyd.dao.EnclosureDao;
import com.zyd.dao.EnclosureVehicleDao;
import com.zyd.exception.BusinessException;
import com.zyd.io.model.*;
import com.zyd.io.page.PageBean;
import com.zyd.io.page.SearchKey;
import com.zyd.io.vo.page.MultiQueryPageVO;
import com.zyd.mappers.CountyEntityMapper;
import com.zyd.mappers.StationEntityMapper;
import com.zyd.pojo.Enclosure;
import com.zyd.service.enclosure.EnclosureService;
import com.zyd.service.power.PowerService;
import com.zyd.util.PointUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 电子围栏业务层
 *
 * @Author: caicaicainiaoa
 * @Date: 2019/4/2  11:42
 */
@Service
public class EnclosureServiceImpl implements EnclosureService {

    @Autowired
    private EnclosureDao enclosureDao;

    @Autowired
    private StationEntityMapper stationMapper;

    @Autowired
    private CountyEntityMapper countyMapper;

    @Autowired
    private EnclosureVehicleDao enclosureVehicleDao;

    /**
     * 添加
     * 参数有id为修改  没有id为添加
     *
     * @param map{[id]:123,enclosureName:"围栏名称",stationCodes:["基站code","基站code"], area:"所属地区",
     *                                                                            [enclosureAdministrator]:"围栏管理员",[administratorMobile]:"管理员电话"}
     */
    @Override
    @Transactional
    public void save(Map<String, Object> map) {
        Integer id = null;
        try {
            Object o = map.get("id");
            if (o instanceof Integer){
                id= (Integer) o;
            }else if (o instanceof String){
                id =Integer.parseInt((String)o);
            }
        } catch (Exception e) {
            System.out.println(LocalTime.now()+" : --"+map);
        }
        String enclosureName = (String) map.get("enclosureName");
        List<String> stationCodeList = (List<String>) map.get("stationCodes");
        String area = (String) map.get("area");
        String enclosureAdministrator = (String) map.get("enclosureAdministrator");
        String mobile = (String) map.get("administratorMobile");
        if (StringUtils.isEmpty(enclosureName)) {
            throw new BusinessException("9000", "围栏名称为空");
        }
        if (StringUtils.isEmpty(area)) {
            throw new BusinessException("9000", "所选地区不能为空");
        }
        if (stationCodeList == null || stationCodeList.size() < 3) {
            throw new BusinessException("9000", "基站不能少于三个");
        }
        Enclosure enclosure = creatEnclosuer(stationCodeList);
        enclosure.setEnclosureName(enclosureName);
        enclosure.setArea(area);
        enclosure.setEnclosureAdministrator(enclosureAdministrator);
        enclosure.setAdministratorMobile(mobile);
        enclosure.setDr(0);
        enclosure.setCarCount(0);
        if (id != null && id != 0) {
            enclosure.setId(id);
        }
        enclosureDao.save(enclosure);


    }

    /**
     * 根据id查询一个
     *
     * @param map {id:2312}
     * @return
     */
    @Override
    public Map findOneById(Map<String, Object> map) {
        HashMap<String, Object> resultMap = new HashMap<>();
        Integer id = null;
        try {
            id = (Integer) map.get("id");
        } catch (Exception e) {
        }
        if (id == null || id == 0) {
            throw new BusinessException(ErrorDef.SYSTEM_ERROR, "=不合法的id=");
        }
        Enclosure enclosure = enclosureDao.getOne(id);
        enclosure.stringToList();
        StationEntityExample example = new StationEntityExample();
        example.createCriteria().andStationcodeIn(enclosure.getExternalStationCodeList()).andDrEqualTo(0);
        List<StationEntity> stationEntities = stationMapper.selectByExample(example);
        resultMap.put("enclosure", enclosure);
        resultMap.put("stationList", stationEntities);
        CountyEntityKey key = new CountyEntityKey();
        key.setId(enclosure.getArea());
        CountyEntity county = countyMapper.selectByPrimaryKey(key);
        resultMap.put("areaName", county.getName());
        return resultMap;
    }

    /**
     * @param map {id:123132}
     */
    @Override
    @Transactional
    public void delete(Map<String, Object> map) {
        Integer id = null;
        try {
            Object o = map.get("id");
            if (o instanceof Integer){
                id= (Integer) o;
            }else if (o instanceof String){
                id =Integer.parseInt((String)o);
            }
        } catch (Exception e) {
            System.out.println(LocalTime.now()+" : --"+map);
        }
        if (id == null || id == 0) {
            throw new BusinessException(ErrorDef.SYSTEM_ERROR, "=不合法的id=");
        }
        enclosureDao.updateDrById(id);
    }

    /**
     * 围栏内车辆统计
     *
     * @param tagCode     车标签
     * @param stationCode 基站code
     * @param isBlackCar  是否为黑车
     */
    @Override
    @Transactional
    public void vehicleCounting(String tagCode, String stationCode, boolean isBlackCar) {
        //查询是否是某围栏的内部基站
        Enclosure enclosurInside = enclosureDao.findTop1ByInsideStationCodesLikeAndDrEquals("%" + stationCode + "%", 0);
        if (enclosurInside != null) { //如果是
            //查询车辆之前的围栏
            Integer enclosureId = enclosureVehicleDao.findEnclosureIdByTagCode(tagCode);
            if (!enclosurInside.getId().equals(enclosureId)) {
                //进围栏
                if (enclosureId == null) { //如果表中没有数据
                    enclosureVehicleDao.insert(enclosurInside.getId(), tagCode);
                } else {
                    enclosureVehicleDao.updateEnclosureIdByTagCode(enclosurInside.getId(), tagCode);
                }
                enclosureDao.increaseCarCountById(enclosurInside.getId());
            }
        } else {
            //是否是某围栏的外围基站
            Enclosure enclosurExternal = enclosureDao.findTop1ByExternalStationCodesLikeAndDrEquals("%" + stationCode + "%", 0);
            if (enclosurExternal != null) {
                //查询车辆之前的围栏
                Integer enclosureId = enclosureVehicleDao.findEnclosureIdByTagCode(tagCode);
                if (enclosureId != null && enclosureId != 0 && enclosureId.equals(enclosurExternal.getId())) {//出围栏
                    enclosureVehicleDao.updateEnclosureIdByTagCode(0, tagCode);
                    enclosureDao.reduceCarCountById(enclosurExternal.getId());
                }
            }
        }


    }

    @Autowired
    private PowerService powerService;
    /**
     * 他前端是模板写死的就是search key我是真没办法 动了 就跟他一样写吧
     *
     * @param multiQueryPageVO
     * @return
     */
    @Override
    public PageBean<Enclosure> findEnclosurePage(MultiQueryPageVO multiQueryPageVO) {
        RolePowerEntity rolePowerEntity = powerService.queryPowerListByUserId((String) HeaderContext.get().get("userid"), "2010");
        if (rolePowerEntity==null ||StringUtils.isEmpty( rolePowerEntity.getArea())) {
            throw new BusinessException("9000","权限不足");
        }
        int currentPage = multiQueryPageVO.getCurrentPage();
        int pageSize = multiQueryPageVO.getPageSize();
        PageRequest pageRequest = new PageRequest(currentPage-1, pageSize);
        List<SearchKey> searchKeys = multiQueryPageVO.getSearchKeys();
        Specification<Enclosure> specification = (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.equal(root.get("dr").as(Integer.class), 0));
            CriteriaBuilder.In<Object> in = cb.in(root.get("area"));
            String[] split = rolePowerEntity.getArea().split(",");
            for (String s : split) {
                in.value(s);
            }
            predicateList.add(in);
            if (searchKeys != null && !searchKeys.isEmpty()) {
                for (SearchKey searchKey : searchKeys) {
                    String name = searchKey.getName();
                    String operate = searchKey.getOperate();
                    String value = searchKey.getValue();
                    if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(operate) && !StringUtils.isEmpty(value)) {
                        if ("like".equalsIgnoreCase(operate)) {
                            predicateList.add(cb.like(root.get(name).as(String.class), "%" + value + "%"));
                        }
                        if (">".equals(operate)) {
                            predicateList.add(cb.greaterThan(root.get(name).as(String.class), value));
                        }
                        if (">=".equals(operate)) {
                            predicateList.add(cb.greaterThanOrEqualTo(root.get(name).as(String.class), value));
                        }
                        if ("<".equals(operate)) {
                            predicateList.add(cb.lessThan(root.get(name).as(String.class), value));
                        }
                        if ("<=".equals(operate)) {
                            predicateList.add(cb.lessThanOrEqualTo(root.get(name).as(String.class), value));
                        }
                        if ("=".equals(operate)) {
                            predicateList.add(cb.equal(root.get(name).as(String.class), value));
                        }
                    }
                }
            }
            return cb.and(predicateList.toArray(new Predicate[0]));
        };
        Page<Enclosure> page = enclosureDao.findAll(specification, pageRequest);
        PageBean<Enclosure> resultPage = new PageBean<>();
        resultPage.setCurrentPage(currentPage);
        resultPage.setItems(page.getContent());
        resultPage.setPageSize(pageSize);
        resultPage.setTotalNum(Integer.valueOf(page.getTotalElements() + ""));

        return resultPage;

    }

    /**
     * 计算所在区域的基站并赋值到实体类上
     *
     * @param externalStationCodeList 外围基站list
     * @return
     */
    private Enclosure creatEnclosuer(List<String> externalStationCodeList) {
        StationEntityExample example = new StationEntityExample();
        example.createCriteria().andStationcodeIn(externalStationCodeList).andDrEqualTo(0);
        List<StationEntity> stationList = stationMapper.selectByExample(example);//查询出外围基站的集合
        List<PointUtils.Point> externalStationPoints = stationsToPoints(stationList);

        StationEntityExample exp = new StationEntityExample();
        exp.createCriteria().andDrEqualTo(0);
        List<StationEntity> stationAll = stationMapper.selectByExample(exp);
        ArrayList<String> insideStationCodeList = new ArrayList<>();
        for (StationEntity station : stationAll) {
            String stationcode = station.getStationcode();
            if (PointUtils.isPtInPoly(Double.parseDouble(station.getJd()), Double.parseDouble(station.getWd()), externalStationPoints) && !externalStationCodeList.contains(stationcode)) {
                insideStationCodeList.add(stationcode);
            }
        }//得到内部基站的集合
        Enclosure enclosure = new Enclosure();
        enclosure.setExternalStationCodeList(externalStationCodeList);
        enclosure.setInsideStationCodeList(insideStationCodeList);
        enclosure.listToString();
        return enclosure;

    }

    /**
     * 将基站转换为 坐标 point
     *
     * @param stationList 基站list
     * @return
     */
    private ArrayList<PointUtils.Point> stationsToPoints(List<StationEntity> stationList) {
        ArrayList<PointUtils.Point> list = new ArrayList<>();
        for (StationEntity station : stationList) {
            list.add(new PointUtils.Point(Double.parseDouble(station.getJd()), Double.parseDouble(station.getWd())));
        }
        return list;
    }

}
